package com.easipass.framework.eirframeworkstream;

import com.easipass.framework.eirframeworkbeanshell.Message;
import com.easipass.framework.eirframeworkbeanshell.ScriptHandle;
import com.easipass.framework.eirframeworkcoredsl.AppNode;
import com.easipass.framework.eirframeworkcoredsl.AppParser;
import com.easipass.framework.eirframeworkcoredsl.SourceDestinationNode;
import com.easipass.framework.eirframeworkjdbc.AppRepository;
import com.easipass.framework.eirframeworkjdbc.AppType;
import com.easipass.framework.eirframeworkjdbc.MessageLogService;
import com.easipass.framework.eirframeworkjdbc.ServiceRepository;
import com.easipass.framework.eirframeworkjdbc.model.App;
import com.easipass.framework.eirframeworkjdbc.model.Service;
import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

@RestController
public class MessageController {

    @Autowired
    private MessageService messageService;

    @Autowired
    private AppRepository appRepository;

    @Autowired
    private ServiceRepository serviceRepository;

    @Autowired
    private MessageLogService messageLogService;

    @RequestMapping("/send/source/{dest}")
    public String sendSource(@PathVariable("dest") String dest,
                             @RequestParam String msg) {
        Service service = serviceRepository.findByName(dest);
        if (service == null) {
            return "dest not found";
        }
        String name = dest + "-" + generatedUnique();
        AppNode appNode = parse(service.getName(), service.getProcess(), true);
        SourceDestinationNode sourceDestinationNode = appNode.getSourceDestinationNode();
        App sourceApp = appRepository.findByNameAndType(sourceDestinationNode.getDestinationName(), AppType.SOURCE.toString());
        Message message = new Message();
        message.setServiceName(dest);
        message.setName(name);
        message.setContent(msg);
        messageLogService.save(name, dest, "$start", msg);
        new ScriptHandle().process(sourceApp.getCode(), message);
        messageLogService.save(name, dest, sourceApp.getName(), new Gson().toJson(message.getContent()));
        messageService.sendSourceMessage(message);
        return message.toString();
    }

    @RequestMapping("/send/sink/{dest}")
    public String sendSink(@PathVariable("dest") String dest,
                           @RequestParam String msg,
                           @RequestParam String name) {
        Message message = new Message();
        message.setServiceName(dest);
        message.setName(name);
        message.setContent(msg);
        App app = appRepository.findByNameAndType(dest, AppType.SINK.toString());
        new ScriptHandle().process(app.getCode(), message);
        messageLogService.save(name, dest, app.getName(), new Gson().toJson(message.getContent()));
        messageService.sendSinkMessage(message);
        return message.toString();
    }

    private String generatedUnique() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        return sdf.format(new Date()) + "-" + new Random().nextInt(1000);
    }

    public AppNode parse(String serviceNmae, String serviceDefinition, boolean validate) {
        return new AppParser(serviceNmae, serviceDefinition, validate).parse();
    }
}
